package utils;
import java.security.PrivateKey;
import java.security.PublicKey;

import cfca.sm2rsa.common.Mechanism;
import cfca.sm2rsa.common.PKIException;
import cfca.util.EnvelopeUtil;
import cfca.util.SignatureUtil2;
import cfca.util.cipher.lib.JCrypto;
import cfca.util.cipher.lib.Session;
import cfca.x509.certificate.X509Cert;

/**
 * 
 * @author cxt-shimanqiang
 *
 */
public class SM2Utils {
	public static Session session = null;
	static {
		try {
			JCrypto.getInstance().initialize(JCrypto.JSOFT_LIB, null);
			session = JCrypto.getInstance().openSession(JCrypto.JSOFT_LIB);
		} catch (PKIException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 1. 裸签－使用己方私钥对明文 M进行签名
	 */
	public static String signRaw(String sourceData, String secuNo) throws Exception{
        PrivateKey priKey = MapCache.getCustPrivateKey(secuNo);
        return new String(new SignatureUtil2().p1SignMessage(Mechanism.SM3_SM2, sourceData.getBytes("UTF8"), priKey, session));
	}
	
	/**
	 * 2. 裸签验签－使用接收方公钥进行签名验证
	 */
	public static boolean verifyRaw(String sourceData,String signature) throws Exception{
        X509Cert cert = MapCache.getCMBCCert();
        PublicKey pubKey = cert.getPublicKey();
		return new SignatureUtil2().p1VerifyMessage(Mechanism.SM3_SM2, sourceData.getBytes("UTF8"), signature.getBytes(), pubKey, session);
	}

	
	/**
	 * 3. 加密－使用接收方公钥证书进行数字信封加密； 包含明文信息
	 */
	public static String encrypt(String sourceData) throws Exception{
		X509Cert cert = MapCache.getCMBCCert();
		X509Cert[] certs = {cert};
		byte[] encryptedData = EnvelopeUtil.envelopeMessage(sourceData.getBytes("UTF8"), Mechanism.SM4_CBC, certs);
		return new String(encryptedData,"UTF8");
	}

	/**
	 * 4. 解密－使用已方私钥进行打开数字信封
	 */
	public static String  decrypt(String encryptedData, String secuNo) throws Exception{
		PrivateKey priKey = MapCache.getCustPrivateKey(secuNo);
        X509Cert cert = MapCache.getCustCert(secuNo);
        byte[] sourceData = EnvelopeUtil.openEvelopedMessage(encryptedData.getBytes("UTF8"), priKey, cert,session);
        return  new String(sourceData, "UTF8");
	}

}
